#include"MapApp.hpp"
#include"SatelliteMGR.hpp"
#include"SecIslSNMGR.hpp"
#include"GnssMGR.hpp"
#include"Keti2Mgr.hpp"
#include<filesystem>
#include<fstream>
#include<iostream>
#include"rapidjson/document.h"
#include"../Base/Concurrency/TimeStamp.hpp"

namespace SC_SUN
{


MapApp::MapApp(const std::string& router, uint16_t port, uint16_t sockPort)
    : mRouter(router)
    , mPort(port)
    , mSockPort(sockPort)
{
    mService = std::make_shared<MapService>(router, port);
    mHandler = std::make_shared<MapHandler>(*mService, *this);
    mSatelliteMGR = std::make_shared<SatelliteMGR>(*this);
    mSecIslSNMGR = std::make_shared<SecIslSNManGR>(*this);
    mGnssMGR = std::make_shared<GnssManGR>(*this);
    mKeti2Mgr = std::make_shared<KeTi2Mgr>(*this);
    mSockSessionMgr = std::make_shared<SessionMgr>();
    mSockService = std::make_shared<Service>(*mSockSessionMgr, "0.0.0.0", mSockPort);
    mSockHandler = std::make_shared<CommandHandler>(*this, *mSockService);

    LoadSceneList();
}

MapApp::~MapApp()
{

}

std::vector<std::string> MapApp::LoadSceneList()
{
    using namespace rapidjson;

    std::vector<std::string> ret;
    std::string path = "./config.json";
    if (std::filesystem::exists("./config.json"))
    {
        //读取文件
        int fileLen = std::filesystem::file_size(path);
        std::string data;
        data.resize(fileLen);
        FILE* pf = fopen(path.data(), "rb");
        fread(data.data(), 1, fileLen, pf);
        fclose(pf);

        //解析数据
        Document doc;
        doc.Parse(data.data());
        auto obj = doc.GetObj();

        auto array = obj["scenes"].GetArray();
        for (int i = 0; i < array.Size(); i++)
        {
            ret.push_back(array[i].GetString());
        }

        mCurScene = ret[0];
        mSceneList = ret;
    }
    else
    {
        mSceneList.push_back(mCurScene);
    }
    return ret;
}

bool MapApp::LoadScene()
{
    using namespace rapidjson;

    //读取配置文件目录
    std::string path = CurScene() + "/Data_Summary/Scenario_Info.json";

    //读取字符串数据
    int fileLen = std::filesystem::file_size(path);
    std::string data;
    data.resize(fileLen);
    FILE* pf = fopen(path.data(), "rb");
    fread(data.data(), 1, fileLen, pf);
    fclose(pf);

    //解析json数据
    Document doc;
    doc.Parse(data.data());
    auto obj = doc.GetObj();

    mSceneData.mStartTime.JD = obj["JD_MS"].GetDouble();
    mSceneData.mStartTime.YY = obj["UTC_start"].GetArray()[0].GetUint();
    mSceneData.mStartTime.MM = obj["UTC_start"].GetArray()[1].GetUint();
    mSceneData.mStartTime.DD = obj["UTC_start"].GetArray()[2].GetUint();
    mSceneData.mStartTime.HH = obj["UTC_start"].GetArray()[3].GetUint();
    mSceneData.mStartTime.MI = obj["UTC_start"].GetArray()[4].GetUint();
    mSceneData.mStartTime.SS = obj["UTC_start"].GetArray()[5].GetDouble();

    mSceneData.mEndTime.JD = obj["JD_ME"].GetDouble();
    mSceneData.mEndTime.YY = obj["UTC_end"].GetArray()[0].GetUint();
    mSceneData.mEndTime.MM = obj["UTC_end"].GetArray()[1].GetUint();
    mSceneData.mEndTime.DD = obj["UTC_end"].GetArray()[2].GetUint();
    mSceneData.mEndTime.HH = obj["UTC_end"].GetArray()[3].GetUint();
    mSceneData.mEndTime.MI = obj["UTC_end"].GetArray()[4].GetUint();
    mSceneData.mEndTime.SS = obj["UTC_end"].GetArray()[5].GetDouble();

    mSceneData.ST_TT = obj["ST_TT"].GetDouble();
    mSceneData.CST_NUM = obj["CST_NUM"].GetUint();
    mSceneData.SAT_NUM = obj["SAT_NUM"].GetUint();

    return true;
}

bool MapApp::Start()
{
    mService->Start();
    mHandler->Start();
    mSockService->Start();
    mSockHandler->Start();

    std::chrono::microseconds start = MMF::TimeStamp::GetUsTime();
    LoadScene();
    mSatelliteMGR->LoadData();
    mGnssMGR->LoadData();
    mSecIslSNMGR->LoadData();
    mKeti2Mgr->LoadData();
    std::chrono::microseconds end = MMF::TimeStamp::GetUsTime();
    std::cout << "Scene Load Cost:" << (end - start).count() << "us" << std::endl;

    return true;
}

void MapApp::Stop()
{
    mService->Stop();
    mHandler->Stop();
    mSockService->Stop();
    mSockHandler->Stop();
}

void MapApp::setSliceIdx(uint64_t slice)
{
    mSliceIdx = slice;
}

uint64_t MapApp::GetSliceIdx()
{
    return mSliceIdx;
}

const std::string& MapApp::CurScene()
{
    return mCurScene;
}

const std::vector<std::string> MapApp::GetSceneList()
{
    return mSceneList;
}

void MapApp::setCurScene(const std::string& curScene)
{
    mCurScene = curScene;
    LoadScene();
    mSliceIdx = 0;
}

EvSceneData MapApp::GetScene()
{
    return mSceneData;
}


SceneTimeInfoMsg MapApp::GetSceneTimeInfo()
{
    SceneTimeInfoMsg ret;

    

    return ret;
}


}
